#include "seqiot.h"
#include "model.h"
#include "sqlite.h"

#define SQL_THING_MODEL_COLS "tag,name,segment,product,metric,catalog,data_type\
,swap_byte,swap_word,swap_dword,writable,value_type\
,is_mul_u,is_mul_i,data_identifier,digit,decimal\
,scale,adjust,valid_max,valid_min,time_tag,time_type"

thing_model_t *thing_model_new() {
    return z_calloc(1, sizeof(thing_model_t));
}

void thing_model_free(thing_model_t *model) {
    if (!model) return;

    z_free(model);
}

uint16_t thing_model_tag_id(thing_model_t *model) {
    return model->segment * 0x1000 + model->super.id + 1;
}

void read_row_thing_model(sqlite3_stmt *stmt, thing_model_t *rs) {
    int idx = 2;
    read_row_object(stmt, &rs->super);

    rs->segment = sqlite3_column_int(stmt, idx++);
    rs->product = sqlite3_column_int(stmt, idx++);
    read_row_str(stmt, idx++, rs->metric, sizeof(rs->metric));
    replace_metric(rs->metric, sizeof(rs->metric));
    rs->catalog = sqlite3_column_int(stmt, idx++);
    rs->data_type = sqlite3_column_int(stmt, idx++);

    rs->swap_byte = sqlite3_column_int(stmt, idx++);
    rs->swap_word = sqlite3_column_int(stmt, idx++);
    rs->swap_dword = sqlite3_column_int(stmt, idx++);

    rs->writable = sqlite3_column_int(stmt, idx++);

    rs->value_type = sqlite3_column_int(stmt, idx++);
    rs->mul_u = sqlite3_column_int(stmt, idx++);
    rs->mul_i = sqlite3_column_int(stmt, idx++);

    rs->data_identifier = sqlite3_column_int(stmt, idx++);
    rs->digit = sqlite3_column_int(stmt, idx++);
    rs->decimal = sqlite3_column_int(stmt, idx++);

    rs->scale = sqlite3_column_double(stmt, idx++);
    rs->adjust = sqlite3_column_double(stmt, idx++);

    rs->valid_max = sqlite3_column_double(stmt, idx++);
    rs->valid_min = sqlite3_column_double(stmt, idx++);

    rs->time_tag = sqlite3_column_int(stmt, idx++);
    rs->time_type = sqlite3_column_int(stmt, idx++);
}

int read_stmt_thing_models(sqlite3 *db, product_t *product) {
    int rc;
    sqlite3_stmt *stmt = NULL;
    char sql[1024];

    sprintf(sql, "SELECT %s FROM thing_model WHERE product=? ORDER BY segment,tag", SQL_THING_MODEL_COLS);
    rc = sqlite3_prepare(db, sql, -1, &stmt, NULL);
    if (SQLITE_OK != rc) {
        sqlite_check(db);
        goto err;
    }

    rc = sqlite3_bind_int(stmt, 1, product->super.id);
    if (SQLITE_OK != rc) {
        sqlite_check(db);
        goto err;
    }

    while (SQLITE_ROW == sqlite3_step(stmt)) {
        thing_model_t *tag = thing_model_new();
        read_row_thing_model(stmt, tag);
        vector_add(&product->thing_model[tag->segment], tag);
    }

    err:
    sqlite3_finalize(stmt);
    return rc;
}